﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ZR.Infrastructure.ANet
{
    public class DESUtil
    {

        /// <summary>
        /// 主题库DES加密
        /// </summary>
        /// <param name="input">待加密数据源</param>
        /// <returns></returns>
        public static string ThemeDesEncrypt(string input)
        {
            string result = string.Empty;
            if(!string.IsNullOrEmpty(input)) {
                try
                {
                    var tripleDES = TripleDES.Create();
                    byte[] inputArray = Encoding.UTF8.GetBytes(input);

                    #region key字节数组处理
                    //主题库加密请求json默认key为空,MD5加密
                    string md5key = Base64Util.MD5Encrypt("").ToLower();
                    //keyBase64解码
                    byte[] keyArr = Base64Util.DecodeBuffer(md5key);
                    //C#的byte编码范围0-255，需转换为java的-128~127
                    byte[] keyCharpe = JavaBase64(keyArr);
                    tripleDES.Key = keyCharpe;
                    #endregion

                    #region IV向量数组处理
                    //粤公平主题库默认向量
                    string sIV = "OGlrbXJmdjU=";
                    byte[] ivArr = Base64Util.DecodeBuffer(sIV);
                    byte[] ivCharpe = JavaBase64(ivArr);
                    tripleDES.IV = ivCharpe;
                    #endregion

                    tripleDES.Mode = CipherMode.CBC;
                    tripleDES.Padding = PaddingMode.PKCS7;
                    ICryptoTransform cTransform = tripleDES.CreateEncryptor();
                    byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
                    result= Convert.ToBase64String(resultArray, 0, resultArray.Length);
                }
                catch(Exception)
                {

                }
            }

            return result;
            
           
        }


        /// <summary>
        /// 通用数据DES加密
        /// </summary>
        /// <param name="input">待加密的数据</param>
        /// <param name="key">密钥Key</param>
        /// <returns></returns>
        public static string DesEncrypt(string input, string key)
        {

            byte[] inputArray = Encoding.UTF8.GetBytes(input);
            var tripleDES = TripleDES.Create();
            var byteKey = Encoding.UTF8.GetBytes(key);
            //复制前8位补全后8位
            byte[] allKey = new byte[24];
            Buffer.BlockCopy(byteKey, 0, allKey, 0, 16);
            Buffer.BlockCopy(byteKey, 0, allKey, 16, 8);
            tripleDES.Key = allKey;
            tripleDES.Mode = CipherMode.ECB;
            tripleDES.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = tripleDES.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        /// <summary>
        /// 通用数据DES解密
        /// </summary>
        /// <param name="input">待解密的数据</param>
        /// <param name="key">密钥Key</param>
        /// <returns></returns>
        public static string DesDecrypt(string input, string key)
        {
            byte[] inputArray = Convert.FromBase64String(input);
            var tripleDES = TripleDES.Create();
            var byteKey = Encoding.UTF8.GetBytes(key);
            //复制前8位补全后8位
            byte[] allKey = new byte[24];
            Buffer.BlockCopy(byteKey, 0, allKey, 0, 16);
            Buffer.BlockCopy(byteKey, 0, allKey, 16, 8);
            tripleDES.Key = allKey;
            tripleDES.Mode = CipherMode.ECB;
            tripleDES.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = tripleDES.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
            return Encoding.UTF8.GetString(resultArray);
        }


        /// <summary>
        /// base64的0~255转换为java的-128~127
        /// </summary>
        /// <param name="by"></param>
        /// <returns></returns>
        public static byte[] JavaBase64(byte[] by)
        {
            sbyte[] sby = new sbyte[by.Length];
            for (int i = 0; i < by.Length; i++)
            {
                if (by[i] > 127)
                    sby[i] = (sbyte)(by[i] - 256);
                else
                    sby[i] = (sbyte)by[i];
            }
            byte[] newby = (byte[])(object)sby;
            return newby;
        }

    }
}
